package xin.ryven.car.android

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.animation.DecelerateInterpolator

class LyricsView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    
    // 使用统一的自定义字体
    private val customTypeface: Typeface? by lazy {
        try {
            Typeface.createFromAsset(context.assets, "fonts/music.ttf")
        } catch (e: Exception) {
            null
        }
    }
    
    private val normalPaint = Paint().apply {
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
        textSize = sp2px(18f)
        color = Color.parseColor("#66FFFFFF") // 更灰的白色，提供明显的层次感
        typeface = customTypeface
    }
    
    private val highlightPaint = Paint().apply {
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
        textSize = sp2px(24f)
        color = Color.WHITE // 纯白色高亮
        isFakeBoldText = true
        typeface = customTypeface
    }
    
    private var lyrics: List<LyricLine> = listOf(LyricLine(0, "暂无歌词"))
    private var currentPosition = 0
    private var offsetY = 0f
    private val lineHeight = dp2px(42f)
    private var marqueeOffsetX = 0f
    private var marqueeAnimator: ValueAnimator? = null
    
    private val scrollAnimator = ValueAnimator().apply {
        duration = 300
        interpolator = DecelerateInterpolator()
        addUpdateListener { animation ->
            offsetY = animation.animatedValue as Float
            invalidate()
        }
    }
    
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        offsetY = h / 2f
        setupMarquee()
        invalidate()
    }
    
    fun updateLyrics(lyrics: List<LyricLine>) {
        this.lyrics = lyrics.ifEmpty {
            listOf(LyricLine(0, "暂无歌词"))
        }
        currentPosition = 0
        offsetY = height / 2f
        setupMarquee()
        invalidate()
    }
    
    fun updatePosition(position: Long) {
        if (lyrics.size <= 1) return  // 只有一行"暂无歌词"时不滚动
        
        val index = lyrics.indexOfLast { it.timestamp <= position }
        if (index != currentPosition && index >= 0) {
            currentPosition = index
            scrollToCurrentLine()
            setupMarquee()
        }
    }
    
    private fun scrollToCurrentLine() {
        val targetY = height / 2f - currentPosition * lineHeight
        scrollAnimator.cancel()  // 取消正在进行的动画
        scrollAnimator.setFloatValues(offsetY, targetY)
        scrollAnimator.start()
    }

    private fun setupMarquee() {
        val line = lyrics.getOrNull(currentPosition) ?: return
        val w = width
        if (w <= 0) return
        val overflow = highlightPaint.measureText(line.text) - w
        if (overflow > 0f) {
            marqueeAnimator?.cancel()
            marqueeOffsetX = 0f
            marqueeAnimator = ValueAnimator.ofFloat(0f, overflow).apply {
                duration = (overflow / 40f * 1000).toLong().coerceAtLeast(1500L)
                repeatMode = ValueAnimator.REVERSE
                repeatCount = ValueAnimator.INFINITE
                addUpdateListener {
                    marqueeOffsetX = it.animatedValue as Float
                    invalidate()
                }
            }
            marqueeAnimator?.start()
        } else {
            marqueeAnimator?.cancel()
            marqueeOffsetX = 0f
        }
    }
    
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        val centerX = width / 2f
        var y = offsetY
        
        // 计算可见区域
        val visibleTop = -lineHeight
        val visibleBottom = height + lineHeight

        lyrics.forEachIndexed { index, line ->
            // 只绘制可见范围内的歌词
            if (y in visibleTop..visibleBottom) {
                val paint = if (index == currentPosition) highlightPaint else normalPaint
                
                // 基于行索引距离当前播放行的距离来计算透明度
                val alpha = if (index == currentPosition) {
                    255 // 当前歌词保持完全不透明
                } else {
                    // 计算距离当前播放行的距离
                    val lineDistance = kotlin.math.abs(index - currentPosition)
                    // 根据行距离设置透明度，距离越远越透明，最远3行后完全透明
                    when (lineDistance) {
                        1 -> (0.7f * 255).toInt() // 相邻行保持70%透明度
                        2 -> (0.5f * 255).toInt() // 相隔2行保持50%透明度  
                        3 -> (0.3f * 255).toInt() // 相隔3行保持30%透明度
                        else -> (0.15f * 255).toInt() // 更远的行保持15%透明度
                    }
                }
                paint.alpha = alpha
                if (index == currentPosition) {
                    val textWidth = highlightPaint.measureText(line.text)
                    if (textWidth > width) {
                        val old = highlightPaint.textAlign
                        highlightPaint.textAlign = Paint.Align.LEFT
                        canvas.drawText(line.text, -marqueeOffsetX, y, highlightPaint)
                        highlightPaint.textAlign = old
                    } else {
                        canvas.drawText(line.text, centerX, y, highlightPaint)
                    }
                } else {
                    canvas.drawText(line.text, centerX, y, normalPaint)
                }
            }
            y += lineHeight
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        marqueeAnimator?.cancel()
    }
    
    private fun dp2px(dp: Float): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp,
            resources.displayMetrics
        )
    }
    
    private fun sp2px(sp: Float): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP,
            sp,
            resources.displayMetrics
        )
    }
    
    fun setHighlightColor(color: Int) {
        highlightPaint.color = color
        invalidate()
    }
    
    // 设置普通歌词颜色
    fun setNormalColor(color: Int) {
        normalPaint.color = color
        invalidate()
    }
}

data class LyricLine(
    val timestamp: Long,
    val text: String
)